package com.glory.dgcpcpda.activity.cpc;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.glory.dgcpcpda.R;
import com.glory.dgcpcpda.activity.cpc.print.DeviceConnFactoryManager;
import com.glory.dgcpcpda.activity.cpc.print.PrintUtils;
import com.glory.dgcpcpda.activity.cpc.print.PrinterCommand;
import com.glory.dgcpcpda.activity.cpc.print.ThreadPool;
import com.glory.dgcpcpda.base.BaseActivity;
import com.glory.dgcpcpda.base.Constant;
import com.glory.dgcpcpda.base.MyApp;
import com.glory.dgcpcpda.callback.CustomDialogEntityCallBack;
import com.glory.dgcpcpda.entity.EdcEntity;
import com.glory.dgcpcpda.entity.PrintEntity;
import com.glory.dgcpcpda.entity.response.BaseResponseBean;
import com.glory.dgcpcpda.utils.NetUtils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.lzy.okgo.convert.Converter;
import com.lzy.okgo.model.Response;
import com.pda.platform.ui.ui_pdaplatform.callback.FreeUI_EntityCallBack;
import com.pda.platform.ui.ui_pdaplatform.callback.FreeUI_TextCallback;
import com.pda.platform.ui.ui_pdaplatform.dialog.FreeUI_GeneralFragmentDialog;
import com.pda.platform.ui.ui_pdaplatform.utils_public.FreeApi_DialogUtils;
import com.pda.platform.ui.ui_pdaplatform.utils_public.FreeApi_SharePreferencesUtils;
import com.printer.command.EscCommand;
import com.printer.command.LabelCommand;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import butterknife.BindView;
import butterknife.OnClick;

public class CpcPrinterSettingActivity extends BaseActivity {
    @BindView(R.id.tvTitle)
    TextView tvTitle;

    @BindView(R.id.tvBaseSubmit)
    TextView tvBaseSubmit;
    @BindView(R.id.llMain)
    LinearLayout llMain;

    @BindView(R.id.btbluetooth)
    Button btnblue;
    @BindView(R.id.btopenbluetooth)
    Button btnblueopen;
    @BindView(R.id.btotestprint)
    Button btnblueprint;
    @BindView(R.id.etbluetoothaddr)
    TextView tvblueaddr;
    @BindView(R.id.etstatus)
    TextView tvstatus;
    @BindView(R.id.btstatus)
    TextView btstatus;

    /**
     * ESC查询打印机实时状态指令
     */
    private byte[] esc = { 0x10, 0x04, 0x02 };
    /**
     * CPCL查询打印机实时状态指令
     */
    private byte[] cpcl = { 0x1b, 0x68 };
    /**
     * TSC查询打印机状态指令
     */
    private byte[] tsc = { 0x1b, '!', '?' };
    private	 String[] permissions = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.BLUETOOTH
    };
    private ArrayList<String> per = new ArrayList<>();
    private static final int REQUEST_CODE = 0x004;
    private int	id = 0;
    private static final String	TAG	= "MainActivity";
    private ThreadPool threadPool;
    private FreeUI_GeneralFragmentDialog dialog;

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_cpc_printer;
    }

    @Override
    protected void initView() {
        setMainLayout(llMain);
        tvBaseSubmit.setVisibility(View.GONE);

        tvTitle.setText("打印机设置");

        checkPermission();
        requestPermission();

        getStatus();
        tvblueaddr.setText(Constant.PRINTER_ADDR);
    }

    private void getStatus(){
        if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] != null &&
                DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getConnState() )
        {
            tvstatus.setText( getString( R.string.str_conn_state_connected ) + " " + getConnDeviceInfo() );
        } else {
            tvstatus.setText( getString( R.string.str_conn_state_disconnect ) );
        }
    }

    private String getConnDeviceInfo()
    {
        String				str				= "";
        DeviceConnFactoryManager	deviceConnFactoryManager	= DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id];
        if ( deviceConnFactoryManager != null
                && deviceConnFactoryManager.getConnState() )
        {
            if ( "USB".equals( deviceConnFactoryManager.getConnMethod().toString() ) )
            {
                str	+= "USB\n";
                str	+= "USB Name: " + deviceConnFactoryManager.usbDevice().getDeviceName();
            } else if ( "WIFI".equals( deviceConnFactoryManager.getConnMethod().toString() ) )
            {
                str	+= "WIFI\n";
                str	+= "IP: " + deviceConnFactoryManager.getIp() + "\t";
                str	+= "Port: " + deviceConnFactoryManager.getPort();
            } else if ( "BLUETOOTH".equals( deviceConnFactoryManager.getConnMethod().toString() ) )
            {
                str	+= "BLUETOOTH\n";
                str	+= "MacAddress: " + deviceConnFactoryManager.getMacAddress();
            } else if ( "SERIAL_PORT".equals( deviceConnFactoryManager.getConnMethod().toString() ) )
            {
                str	+= "SERIAL_PORT\n";
                str	+= "Path: " + deviceConnFactoryManager.getSerialPortPath() + "\t";
                str	+= "Baudrate: " + deviceConnFactoryManager.getBaudrate();
            }
        }
        return(str);
    }

    private void checkPermission()
    {
        for ( String permission : permissions )
        {
            if ( PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission( this, permission ) )
            {
                per.add( permission );
            }
        }
    }


    private void requestPermission()
    {
        if ( per.size() > 0 )
        {
            String[] p = new String[per.size()];
            ActivityCompat.requestPermissions( this, per.toArray( p ), REQUEST_CODE );
        }
    }

    private void OpenBlueTooth(String addr){
        closeport();
        /*获取蓝牙mac地址*/
        String macAddress = addr;
        /* 初始化话DeviceConnFactoryManager */
        new DeviceConnFactoryManager.Build()
                .setId( id )
                /* 设置连接方式 */
                .setConnMethod( DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH )
                /* 设置连接的蓝牙mac地址 */
                .setMacAddress( macAddress )
                .build();
        /* 打开端口 */
        Log.d(TAG, "onActivityResult: 连接蓝牙"+id);
        threadPool = ThreadPool.getInstantiation();
        threadPool.addTask(() -> DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].openPort());
    }

    /**
     * 重新连接回收上次连接的对象，避免内存泄漏
     */
    private void closeport()
    {
        if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] != null &&DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].mPort != null )
        {
            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].reader.cancel();
            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].mPort.closePort();
            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].mPort = null;
        }
    }

    /**
     * 打印机状态查询
     *
     * @param view
     */
    public void btnPrinterState( View view )
    {
        /* 打印机状态查询 */
        if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] == null ||
                !DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getConnState() )
        {
            PrintUtils.toast( this, getString( R.string.str_cann_printer ) );
            return;
        }
        DeviceConnFactoryManager.whichFlag = true;
        ThreadPool.getInstantiation().addTask(() -> {
            Vector<Byte> data = new Vector<>( esc.length );
            if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getCurrentPrinterCommand() == PrinterCommand.ESC )
            {
                for ( int i = 0; i < esc.length; i++ )
                {
                    data.add( esc[i] );
                }
                DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].sendDataImmediately( data );
            }else if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getCurrentPrinterCommand() == PrinterCommand.TSC )
            {
                for ( int i = 0; i < tsc.length; i++ )
                {
                    data.add( tsc[i] );
                }
                DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].sendDataImmediately( data );
            }else if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getCurrentPrinterCommand() == PrinterCommand.CPCL )
            {
                for ( int i = 0; i < cpcl.length; i++ )
                {
                    data.add( cpcl[i] );
                }
                DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].sendDataImmediately( data );
            }
        });
    }

    void sendLabel()
    {

        FreeUI_EntityCallBack<BaseResponseBean<PrintEntity>> callBack = new CustomDialogEntityCallBack<BaseResponseBean<PrintEntity>>
                (new TypeToken<BaseResponseBean<PrintEntity>>() {
                }.getType(), getSupportFragmentManager(), this) {

            @Override
            public void onSuccess(Response<BaseResponseBean<PrintEntity>> response) {
                super.onSuccess(response);
                if (response.body().isSuccess(getApplicationContext(),false,getSupportFragmentManager())){
                    String Body = response.body().getResponse().getBody().getCode();
                    if(Body.startsWith("NG")){
                        showConfirmDialog(Body);
                    }else{
                        Vector<Byte> datas = new Vector<>();

                        if(StringUtils.isNotEmpty(Body)){
                            String[] result = Body.split(" ");
                            for (String item :result) {
                                int box = Integer.parseInt(item);
                                datas.add((byte)box );
                            }

                            /* 发送数据 */
                            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].sendDataImmediately( datas );
                        }
                    }
                }
            }

            @Override
            public void onError(Response<BaseResponseBean<PrintEntity>> response) {
                super.onError(response);
                loadError(response.getException(),"PeinterTest");
            }
        };
        JsonObject map = new JsonObject();
        map.addProperty("PrintCode","M322");

        NetUtils.requestPostCPC("CPC.PeinterTest","PeinterTest",this, map, callBack);
    }


    @Override
    protected void initData() {
    }

    @OnClick({R.id.tvBaseSubmit, R.id.btbluetooth, R.id.btopenbluetooth, R.id.btotestprint, R.id.btstatus})
    public void onViewClicked(View view) {
        switch (view.getId())   {
            case R.id.tvBaseSubmit:
                break;
            case R.id.btstatus:
                getStatus();
                break;
            case R.id.btbluetooth:
                dialog = FreeApi_DialogUtils.getScanDialog(this, "请输入打印机蓝牙地址", Constant.PRINTER_ADDR, s -> {
                    tvblueaddr.setText(s);
                    Constant.PRINTER_ADDR = s;
                    showToast("保存成功", true);
                    FreeApi_SharePreferencesUtils.setSharePre("DG_CPC_FILE", "PRINTER_ADDR", s, MyApp.app);
                    dialog.dismiss();
                });
                dialog.show(getSupportFragmentManager(), "WEB_URL_DIALOG");
                break;
            case R.id.btopenbluetooth:
                String printerAddr = Constant.PRINTER_ADDR;
                if(StringUtils.isNotEmpty(printerAddr)){
                    //OpenBlueTooth("DC:1D:30:DB:DF:20");
                    OpenBlueTooth(printerAddr);
                }
                break;
            case R.id.btotestprint:
                /* 打印机状态查询 */
                if ( DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] == null ||
                        !DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getConnState() )
                {
                    PrintUtils.toast( this, getString( R.string.str_cann_printer ) );
                    return;
                }
                sendLabel();
                break;
        }
    }

}